#pragma once
#include<iostream>
#include<typeinfo>
#include<cassert>
#include<unistd.h>

class Any
{
private:
    class holder
    {
    public:
        virtual ~holder() {}
        virtual const std::type_info& type() = 0;  
        virtual holder *clone() = 0;
    };

    template <class T>
    class placeholder : public holder
    {
    public:
        placeholder(const T& val):_val(val) {};
        //获取子类对象保存的数据类型
        virtual const std::type_info& type()
        {
            return typeid(T);
        }

        //克隆一个新的子类对象
        virtual holder *clone()
        {
            return new placeholder(_val);
        }

    public:
        T _val;
    };
    holder* _content;

    public:
        Any():_content(nullptr) {}

        template<class T>
        Any(const T& val)
        :_content(new placeholder<T>(val))
        {}

        Any(const Any& other)
        :_content(other._content ? other._content->clone() : nullptr){}     //拷贝构造的对象为空就置为空，非空调用拷贝对象的clone


        ~Any()
        {
            delete _content;
        }

        Any& swap(Any& other)
        {
            std::swap(_content,other._content);
            return *this;
        }

        template<class T>
        T* get()   //返回子类对象保存数据的指针
        {
            //获取类型与保存类型必须一致
            assert(typeid(T) == _content->type());
            return &((placeholder<T>*)_content)->_val;   //考虑好优先级  基类指针强转为派生类才能访问派生类对象中存储的数据
        }
        template<class T>
        Any& operator=(const T& val)   //赋值运算符重载函数
        {
            //类似于现代写法
            Any(val).swap(*this);  
            return *this;       //返回引用 为了能连续赋值
        }

        Any& operator=(const Any& other)
        {
            Any(other).swap(*this);
            return *this;
        }

};
